1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172
#![allow(non_camel_case_types, non_snake_case)]
use crate::co;
use crate::comctl::ffi;
use crate::decl::*;
use crate::kernel::privs::*;
use crate::ole::privs::*;
use crate::prelude::*;
impl comctl_Hwnd for HWND {}
/// This trait is enabled with the `comctl` feature, and provides methods for
/// [`HWND`](crate::HWND).
///
/// Prefer importing this trait through the prelude:
///
/// ```no_run
/// use winsafe::prelude::*;
/// ```
pub trait comctl_Hwnd: user_Hwnd {
/// [`DefSubclassProc`](https://learn.microsoft.com/en-us/windows/win32/api/commctrl/nf-commctrl-defsubclassproc)
/// function.
///
/// The return type is variable, being defined by the `RetType` associated
/// type of the [`MsgSend`](crate::prelude::MsgSend) trait. That means each
/// message can define its own return type.
///
/// # Safety
///
/// Messages manipulate pointers, copies and window states. Improper use may
/// lead to undefined behavior.
unsafe fn DefSubclassProc<M>(&self, msg: M) -> M::RetType
where M: MsgSend,
{
let mut msg = msg;
let wm_any = msg.as_generic_wm();
msg.convert_ret(
ffi::DefSubclassProc(
self.ptr(), wm_any.msg_id.raw(), wm_any.wparam, wm_any.lparam,
),
)
}
/// [`InitializeFlatSB`](https://learn.microsoft.com/en-us/windows/win32/api/commctrl/nf-commctrl-initializeflatsb)
/// function.
fn InitializeFlatSB(&self) -> HrResult<()> {
ok_to_hrresult(unsafe { ffi::InitializeFlatSB(self.ptr()) })
}
/// [`RemoveWindowSubclass`](https://learn.microsoft.com/en-us/windows/win32/api/commctrl/nf-commctrl-removewindowsubclass)
/// function.
fn RemoveWindowSubclass(&self,
subclass_func: SUBCLASSPROC,
subclass_id: usize,
) -> SysResult<()>
{
bool_to_sysresult(
unsafe {
ffi::RemoveWindowSubclass(
self.ptr(),
subclass_func as _,
subclass_id,
)
},
)
}
/// [`SetWindowSubclass`](https://learn.microsoft.com/en-us/windows/win32/api/commctrl/nf-commctrl-setwindowsubclass)
/// function.
///
/// # Safety
///
/// You must provide a subclass procedure.
unsafe fn SetWindowSubclass(&self,
subclass_proc: SUBCLASSPROC,
subclass_id: usize,
ref_data: usize,
) -> SysResult<()>
{
bool_to_sysresult(
unsafe {
ffi::SetWindowSubclass(
self.ptr(),
subclass_proc as _,
subclass_id,
ref_data,
)
},
)
}
/// [`TaskDialog`](https://learn.microsoft.com/en-us/windows/win32/api/commctrl/nf-commctrl-taskdialog)
/// function.
///
/// If you need more customization, see the
/// [`TaskDialogIndirect`](crate::TaskDialogIndirect) function.
///
/// # Examples
///
/// An information message with just an OK button:
///
/// ```no_run
/// use winsafe::{self as w, prelude::*, co};
///
/// let hwnd: w::HWND; // initialized somewhere
/// # let hwnd = w::HWND::NULL;
///
/// hwnd.TaskDialog(
/// Some("Operation successful"),
/// None,
/// Some("The operation completed successfully."),
/// co::TDCBF::OK,
/// w::IconRes::Info,
/// )?;
/// # w::HrResult::Ok(())
/// ```
///
/// Prompt the user to click OK or Cancel upon a question:
///
/// ```no_run
/// use winsafe::{self as w, prelude::*, co};
///
/// let hwnd: w::HWND; // initialized somewhere
/// # let hwnd = w::HWND::NULL;
///
/// let answer = hwnd.TaskDialog(
/// Some("My app name"),
/// Some("File modified"),
/// Some("The file has been modified.\nProceed closing the application?"),
/// co::TDCBF::OK | co::TDCBF::CANCEL,
/// w::IconRes::Warn,
/// )?;
///
/// if answer == co::DLGID::OK {
/// println!("User clicked OK.");
/// }
/// # w::HrResult::Ok(())
/// ```
fn TaskDialog(&self,
window_title: Option<&str>,
main_instruction: Option<&str>,
content: Option<&str>,
common_buttons: co::TDCBF,
icon: IconRes,
) -> HrResult<co::DLGID>
{
// https://weblogs.asp.net/kennykerr/Windows-Vista-for-Developers-_1320_-Part-2-_1320_-Task-Dialogs-in-Depth
let mut pn_button = i32::default();
let (hinst, raw_ico) = icon.as_ptr();
ok_to_hrresult(
unsafe {
ffi::TaskDialog(
self.ptr(),
hinst.ptr(),
WString::from_opt_str(window_title).as_ptr(),
WString::from_opt_str(main_instruction).as_ptr(),
WString::from_opt_str(content).as_ptr(),
common_buttons.raw(),
raw_ico,
&mut pn_button,
)
},
).map(|_| unsafe { co::DLGID::from_raw(pn_button as _) })
}
/// [`UninitializeFlatSB`](https://learn.microsoft.com/en-us/windows/win32/api/commctrl/nf-commctrl-uninitializeflatsb)
/// function.
fn UninitializeFlatSB(&self) -> HrResult<()> {
ok_to_hrresult(unsafe { ffi::UninitializeFlatSB(self.ptr()) })
}
}